/*
 * @Author: Xujianchen
 * @Date: 2025-11-17 21:13:28
 * @LastEditors: Xujianchen
 * @LastEditTime: 2025-11-17 21:28:33
 * @Description: http请求
 */
import { message, notification } from 'ant-design-vue'
import { getToken, removeToken, removeUser } from '@/app/storage'
import { LOGIN_NAME } from '@/const/router'
import router from '@/router'
import axios, { type AxiosResponse } from 'axios'

import type { CustomAxiosRequestConfig } from './type'

const instance = axios.create({
  baseURL:
    import.meta.env.MODE === 'development'
      ? '/api'
      : 'https://mock.presstime.cn/mock/67282170caf0b4e52f14102d/api',
  timeout: 80000,
}) as unknown as ReturnType<typeof axios.create>

const LOGIN_LOSE_EFFICACY_TEXT = '登录状态失效，请重新登录'

// 请求拦截
instance.interceptors.request.use(
  (config: CustomAxiosRequestConfig) => {
    const token = getToken()
    if (!token) {
      message.warning(LOGIN_LOSE_EFFICACY_TEXT)
      removeToken()
      removeUser()
      setTimeout(() => router.replace(`/${LOGIN_NAME}`), 500)
      return Promise.reject(new Error(LOGIN_LOSE_EFFICACY_TEXT))
    }

    config.headers = config.headers ?? {}
    ;(config.headers as any).token = token

    return config
  },
  (error) => Promise.reject(error),
)

// 响应拦截
instance.interceptors.response.use(
  (res: AxiosResponse) => {
    const { data, config } = res
    const options = (config as CustomAxiosRequestConfig).options

    if ([403, 401].includes(+data.code)) {
      message.warning(LOGIN_LOSE_EFFICACY_TEXT)
      removeToken()
      removeUser()
      setTimeout(() => router.replace(`/${LOGIN_NAME}`), 500)
      return Promise.reject(data.message)
    }

    if (res.status !== 200) {
      notification.error(data.message || options?.errorText)
      return Promise.reject(data.message)
    }

    if (options?.successText) {
      notification.success(data.message || options.successText)
    }

    return data
  },
  (error) => {
    const ERROR_CODES_MAP: Record<number, string> = {
      400: '请求错误',
      401: '未授权，请登录',
      403: '拒绝访问',
      404: '请求地址不存在',
      500: '服务器繁忙',
      502: '网关错误',
      503: '服务不可用，服务器暂时过载或维护',
      504: '网关超时',
    }
    notification.error({
      message: '请求错误',
      description: !error.response
        ? '网络连接异常'
        : ERROR_CODES_MAP[error.response.status] || '请求错误',
    })

    return Promise.reject(new Error('请求错误'))
  },
)

export default instance
